package com.pansoft.xmlparse;

import android.text.TextUtils;

import com.pansoft.resmanager.ResFileManager;

import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

import java.io.File;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

/**
 * 解析setting.xml配置文件
 * Created by slp on 2018/4/8.
 */
public class SettingParser {

    private static String TAG_SERVICE = "node";
    private static SettingParser sSettingParser;
    private NodeList nodeList;

    private SettingParser() {
        super();
        String resPath = ResFileManager.PACKAGE_DIR + File.separator + "Setting.xml";
        nodeList = parseXML(resPath);
    }

    public static synchronized SettingParser getInstance() {
        if (sSettingParser == null) {
            sSettingParser = new SettingParser();
        }
        return sSettingParser;
    }

    private NodeList parseXML(String path) {
        NodeList nodeList = null;
        File file = new File(path);
        String xmlString = ResFileManager.decryptFile(file);
        try {
            Element rootElement = stringToElement(xmlString);
            String id = rootElement.getAttribute("id");
            if ("setting".equals(id)) {
                nodeList = rootElement.getElementsByTagName(TAG_SERVICE);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return nodeList;
    }

    public Map<String, String> getElementById(String id) {
        for (int i = 0; i < nodeList.getLength(); i++) {
            Element element = (Element) nodeList.item(i);
            String tempId = element.getAttribute("id");
            if (tempId != null && tempId.equals(id)) {
                NamedNodeMap namedNodeMap = element.getAttributes();
                Map<String, String> map = new HashMap<String, String>();
                for (int j = 0; j < namedNodeMap.getLength(); j++) {
                    Attr attr = (Attr) namedNodeMap.item(j);
                    map.put(attr.getName(), attr.getValue());
                }
                return map;
            }
        }
        return null;
    }

    /**
     * 获取全部节点的信息
     * @return map
     */
    public Map<String, String> getAllElements() {
        Map<String, String> map = new HashMap();
        for (int i = 0; i < nodeList.getLength(); i++) {
            String key = null;
            String value = null;
            Element element = (Element) nodeList.item(i);
            NamedNodeMap namedNodeMap = element.getAttributes();

            for (int j = 0; j < namedNodeMap.getLength(); j++) {
                Attr attr = (Attr) namedNodeMap.item(j);
                if("id".equals(attr.getName())){
                    key = attr.getValue();
                }else if("value".equals(attr.getName())){
                    value = attr.getValue();
                }
            }
            map.put(key, value);
        }
        return map;
    }

    /**
     * 通过属性名查找节点
     *
     * @param attrName
     * @return
     */
    public List<Element> getElementsByAttr(String attrName) {
        ArrayList<Element> elements = new ArrayList<>();
        if (TextUtils.isEmpty(attrName)) {
            throw new IllegalArgumentException("attr can not  null");
        }
        for (int i = 0; i < nodeList.getLength(); i++) {
            Element element = (Element) nodeList.item(i);
            if (element.hasAttribute(attrName)) {
                elements.add(element);

            }
        }
        return elements;
    }

    /**
     * @param xml
     * @return
     * @throws Exception
     */
    public static Element stringToElement(String xml) throws Exception {
        StringReader sr = new StringReader(xml);
        InputSource is = new InputSource(sr);
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document doc = builder.parse(is);
        Element rootElement = doc.getDocumentElement();
        return rootElement;

    }
}
